package com.macro.mall.boot.wechat.mp;

import com.macro.mall.boot.wechat.util.WechatSpringUtils;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.enums.TicketType;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.concurrent.TimeUnit;

/**
 * 微信小程序redis配置
 *
 * @author rainn
 * @date 2019-02-27
 */
public class WxMpInRedisConfig extends WxMpInMemoryConfigStorage {

    private static final String ACCESS_TOKEN_KEY_PREFIX = "com.mg.live.wechat:token";

    private String appId;

    public WxMpInRedisConfig(String appId) {
        this.appId = appId;
    }

    @Override
    public String getAccessToken() {
        return getAccessTokenInternal();
    }

    @Override
    public boolean isAccessTokenExpired() {
        StringRedisTemplate stringRedisTemplate = WechatSpringUtils.getBean(StringRedisTemplate.class);
        String key = getRedisKey();
        return !stringRedisTemplate.hasKey(key);
    }

    @Override
    public void expireAccessToken() {
        StringRedisTemplate stringRedisTemplate = WechatSpringUtils.getBean(StringRedisTemplate.class);
        String key = getRedisKey();
        stringRedisTemplate.delete(key);
    }

    @Override
    public synchronized void updateAccessToken(WxAccessToken accessToken) {
        updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
    }

    @Override
    public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
        StringRedisTemplate stringRedisTemplate = WechatSpringUtils.getBean(StringRedisTemplate.class);
        String key = getRedisKey();

        stringRedisTemplate.opsForValue().set(key, accessToken, expiresInSeconds - 1200, TimeUnit.SECONDS);
    }

    /**
     * 获取微信token对象
     *
     * @return 微信token对象
     */
    private String getAccessTokenInternal() {
        StringRedisTemplate stringRedisTemplate = WechatSpringUtils.getBean(StringRedisTemplate.class);
        String key = getRedisKey();

        String wxAccessTokenJson = stringRedisTemplate.opsForValue().get(key);
        return wxAccessTokenJson;
    }

    /**
     * 获取redis key
     *
     * @return redis key
     */
    private String getRedisKey() {
        return ACCESS_TOKEN_KEY_PREFIX + ":" + appId;
    }

    @Override
    public boolean isTicketExpired(TicketType type) {
        StringRedisTemplate stringRedisTemplate = WechatSpringUtils.getBean(StringRedisTemplate.class);
        String key = getJsTicketRedisKey();
        return !stringRedisTemplate.hasKey(key);
    }

    @Override
    public synchronized void updateTicket(TicketType type, String ticket, int expiresInSeconds) {
        StringRedisTemplate stringRedisTemplate = WechatSpringUtils.getBean(StringRedisTemplate.class);
        String key = getJsTicketRedisKey();

        stringRedisTemplate.opsForValue().set(key, ticket, expiresInSeconds - 1200, TimeUnit.SECONDS);
    }

    @Override
    public String getJsapiTicket() {
        StringRedisTemplate stringRedisTemplate = WechatSpringUtils.getBean(StringRedisTemplate.class);
        String key = getJsTicketRedisKey();

        return stringRedisTemplate.opsForValue().get(key);
    }

    @Override
    public String getTicket(TicketType type) {
        return getJsapiTicket();
    }

    /**
     * 获取redis key
     *
     * @return redis key
     */
    private String getJsTicketRedisKey() {
        return ACCESS_TOKEN_KEY_PREFIX + ":jsticket:" + appId;
    }
}
